專案:利用 Discord Bot 監控 Minecraft 伺服器狀態

專案簡介

為了更方便監控自架的 Minecraft 伺服器狀態,我設計了一個 Discord Bot,能夠定時自動回報伺服器的延遲與在線人數。這個機器人部署於 Ubuntu Server 虛擬機器中,與 Discord 頻道串接,實現伺服器即時狀態通知,並支援指令查詢,提升了管理效率與資訊透明度。

功能說明

• !status 指令:手動查詢伺服器狀態

• 自動通知:每 5 分鐘推播伺服器在線人數與延遲至指定頻道

• 錯誤處理:若伺服器關閉或無法查詢,會回傳錯誤通知

技術細節

• 主要套件:

• discord.py:與 Discord API 溝通

• mcstatus:查詢 Minecraft Java 伺服器狀態

• apscheduler:定時任務排程

• 執行架構:

• 透過 systemd 服務常駐啟動

• Discord bot 實例與事件循環由 asyncio 管理

• 定時任務自動查詢伺服器並回報訊息至 Discord 頻道

實際運作畫面

我的照片

"在伺服器無作動時顯示紅色,反之則為綠色,可使用!status呼叫機器人"

原始碼與部署教學

Github
bot.py

                import os
                import asyncio
                import discord
                from discord.ext import commands
                from dotenv import load_dotenv
                from mcstatus import JavaServer
                from apscheduler.schedulers.asyncio import AsyncIOScheduler

                load_dotenv()

                DISCORD_TOKEN = os.getenv("DISCORD_TOKEN")
                CHANNEL_ID = os.getenv("CHANNEL_ID")
                MC_ADDRESS = os.getenv("MC_ADDRESS")

                if not all([DISCORD_TOKEN, CHANNEL_ID, MC_ADDRESS]):
                    print("⚠️ 請確認 .env 檔案的 DISCORD_TOKEN、CHANNEL_ID、MC_ADDRESS 都有正確設定!")
                    exit(1)

                intents = discord.Intents.default()
                intents.message_content = True

                bot = commands.Bot(command_prefix="!", intents=intents)

                async def send_status():
                    channel = bot.get_channel(int(CHANNEL_ID))
                    if not channel:
                        print(f"⚠️ 找不到頻道 ID {CHANNEL_ID}")
                        return

                    try:
                        server = JavaServer.lookup(MC_ADDRESS)
                        status = await asyncio.get_event_loop().run_in_executor(None, server.status)

                        embed = discord.Embed(title="🟢 Minecraft Server Status", color=0x00ff00)
                        embed.add_field(name="延遲", value=f"{status.latency:.1f} ms", inline=True)
                        embed.add_field(name="人數", value=f"{status.players.online}/{status.players.max}", inline=True)
                    except Exception as e:
                        embed = discord.Embed(title="🔴 Minecraft Server Status", description=str(e), color=0xff0000)

                    await channel.send(embed=embed)

                @bot.event
                async def on_ready():
                    print(f"✅ Discord Bot 啟動成功!登入帳號:{bot.user}")
                    scheduler = AsyncIOScheduler()
                    scheduler.add_job(send_status, "interval", minutes=5)
                    scheduler.start()

                @bot.command(name="status")
                async def manual_status(ctx):
                    try:
                        server = JavaServer.lookup(MC_ADDRESS)
                        status = server.status()

                        embed = discord.Embed(title="🟢 Minecraft Server Status", color=0x00ff00)
                        embed.add_field(name="延遲", value=f"{status.latency:.1f} ms", inline=True)
                        embed.add_field(name="人數", value=f"{status.players.online}/{status.players.max}", inline=True)
                    except Exception as e:
                        embed = discord.Embed(title="🔴 Minecraft Server Status", description=str(e), color=0xff0000)

                    await ctx.send(embed=embed)

                if __name__ == "__main__":
                    bot.run(DISCORD_TOKEN)

                
mcstatusbot.service

                [Unit]
                Description=Minecraft Server Status Discord Bot
                After=network.target

                [Service]
                Type=simple
                User=root
                WorkingDirectory=/root/mc-status-bot
                ExecStart=/root/mc-status-bot/venv/bin/python /root/mc-status-bot/bot.py
                Restart=always
                RestartSec=10

                [Install]
                WantedBy=multi-user.target


                
env.env

                DISCORD_TOKEN=(你的機器人TOKEN)
                CHANNEL_ID=(想發文的頻道ID)
                MC_ADDRESS=(你想監控的IP)

                

心得

這個專案讓我更深入掌握了 Python 與 Discord Bot 的實作流程,並學習如何在 Linux 環境中部署常駐服務。也實際運用 mcstatus 與 apscheduler 實現 Minecraft 狀態查詢與自動推播。 在過程中我也遇到了一些挑戰,例如 .env 的讀取問題、systemd 服務未自動啟動、Bot 無法連線的排查等,但也因此學會了更多關於 Linux 管理與 Debug 的技巧。

← 返回首頁